package com.desktopmng.service;

import java.io.Serializable;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.criterion.Criterion;
import org.springframework.util.Assert;
import com.desktopmng.core.utils.GenericsUtils;


@SuppressWarnings("unchecked")
public class HibernateEntityDao<T> extends HibernateGenericDao implements EntityDao<T> {
	protected Class<T> entityClass;// DAO所管理的Entity类型.

	/**
	 * 在构造函数中将泛型T.class赋给entityClass.
	 */
	public HibernateEntityDao() {
		entityClass = GenericsUtils.getSuperClassGenricType(getClass());
	}

	/**
	 * 取得Entity的Criteria.
	 * 
	 * @see HibernateGenericDao#createCriteria(Class,Criterion[])
	 */
	public Criteria createCriteria(Criterion... criterions) {
		return createCriteria(getEntityClass(), criterions);
	}

	/**
	 * 取得Entity的Criteria,带排序参数.
	 * 
	 * @see HibernateGenericDao#createCriteria(Class,String,boolean,Criterion[])
	 */
	public Criteria createCriteria(String orderBy, boolean isAsc, Criterion... criterions) {
		return createCriteria(getEntityClass(), orderBy, isAsc, criterions);
	}

	/**
	 * 消除与 Hibernate Session 的关联
	 * 
	 * @param entity
	 */
	public void evict(Object entity) {
		getHibernateTemplate().evict(entity);
	}

	/**
	 * 根据属性名和属性值查询对象.
	 * 
	 * @return 符合条件的对象列表
	 * @see HibernateGenericDao#findBy(Class,String,Object)
	 */
	public List<T> findBy(String propertyName, Object value) {
		return findBy(getEntityClass(), propertyName, value);
	}

	/**
	 * 根据属性名和属性值查询对象,带排序参数.
	 * 
	 * @return 符合条件的对象列表
	 * @see HibernateGenericDao#findBy(Class,String,Object,String,boolean)
	 */
	public List<T> findBy(String propertyName, Object value, String orderBy, boolean isAsc) {
		return findBy(getEntityClass(), propertyName, value, orderBy, isAsc);
	}

	/**
	 * 根据属性名和属性值查询单个对象.
	 * 
	 * @return 符合条件的唯一对象 or null
	 * @see HibernateGenericDao#findUniqueBy(Class,String,Object)
	 */
	public T findUniqueBy(String propertyName, Object value) {
		return findUniqueBy(getEntityClass(), propertyName, value);
	}

	/**
	 * 根据ID获取对象.
	 * 
	 * @see HibernateGenericDao#getId(Class,Object)
	 */
	public T get(Serializable id) {
		return get(getEntityClass(), id);
	}

	/**
	 * 获取全部对象
	 * 
	 * @see HibernateGenericDao#getAll(Class)
	 */
	public List<T> getAll() {
		return getAll(getEntityClass());
	}

	/**
	 * 获取全部对象,带排序参数.
	 * 
	 * @see HibernateGenericDao#getAll(Class,String,boolean)
	 */
	public List<T> getAll(String orderBy, boolean isAsc) {
		return getAll(getEntityClass(), orderBy, isAsc);
	}

	/**
	 * 判断对象某些属性的值在数据库中唯一.
	 * 
	 * @param uniquePropertyNames 在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password"
	 * @see HibernateGenericDao#isUnique(Class,Object,String)
	 */
	public boolean isUnique(Object entity, String uniquePropertyNames) {
		return isUnique(getEntityClass(), entity, uniquePropertyNames);
	}

	/**
	 * 根据ID移除对象.
	 * 
	 * @see HibernateGenericDao#removeById(Class,Serializable)
	 */
	public void removeById(Serializable id) {
		removeById(getEntityClass(), id);
	}

//	@Override
//	public boolean save(Object entity) {
//		Assert.isInstanceOf(getEntityClass(), entity);
//		if(onValid((T) entity)){
//			super.save(entity);
//			return true;
//		}else{
//			return false;
//		}
//	}
	
	/* (non-Javadoc)
	 * @see com.zjpii.jfoss.core.dao.HibernateGenericDao#save(java.lang.Object)
	 */
	@Override
	public boolean save(Object entity) {
		Assert.isInstanceOf(getEntityClass(), entity);
		if(onValid((T) entity)){
			super.save(entity);
			return true;
		}else{
			return false;
		}
	}

	public void merge(T entity) {
		getHibernateTemplate().merge(entity);
	}

	public void persist(T entity) {
		getHibernateTemplate().persist(entity);
	}

	public void refresh(T entity) {
		getHibernateTemplate().refresh(entity);
	}

	/**
	 * 取得entityClass.JDK1.4不支持泛型的子类可以抛开Class<T> entityClass,重载此函数达到相同效果。
	 */
	protected Class<T> getEntityClass() {
		return entityClass;
	}

	/**
	 * 与数据库相关的校验,比如判断名字在数据库里有没有重复, 在保存时被调用,在子类重载.
	 * 
	 * @see #save(Object)
	 */
	protected boolean onValid(T entity) {
		return true;	
	}

	/** 
	 * 根据传入的ID字符串集体删除多条记录
	 * Ids 的形式为"id1,id2,id3"
	 * @see com.zjpii.jfoss.core.dao.EntityDao#removeByIds(java.lang.String)
	 */
	public void removeByIds(String Ids) {
		// TODO Auto-generated method stub
		String[] Id = Ids.split(",");
		for(int i=0;i<Id.length;i++){
			this.removeById(new Long(Id[i]));
		}
	}
		
	/**
	 * @see    BasicCRUDService#delete(Object)
	 */
	public void delete(T entity) {
		remove(entity);
	}

	/**
	 * @see    BasicCRUDService#saveOrUpdate(Object)
	 */
	public boolean saveOrUpdate(T entity) {
		return save(entity);
	}
}
